package academic.concordia.bankofquebec.managedbean;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;

import academic.concordia.bankofquebec.bean.client.IClientBean;
import academic.concordia.bankofquebec.bean.payment.IPaymentBean;
import academic.concordia.bankofquebec.bean.session.SessionData;
import academic.concordia.bankofquebec.entity.BankAccount;
import academic.concordia.bankofquebec.entity.Bill;
import academic.concordia.bankofquebec.entity.Payment;
import academic.concordia.bankofquebec.entity.Transaction;

@ManagedBean(name="paymentManagedBean")
@Scope("session")
public class PaymentManagedBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private String accountId;
	
	@ManagedProperty(value="#{SessionData}")
	private SessionData sessionData;
	
	@ManagedProperty(value="#{ClientBean}")
	IClientBean clientBean;
	
	@ManagedProperty(value="#{PaymentBean}")
	private IPaymentBean paymentBean;
	
	private Payment payment;
	
	private Map<String, String> billsAvailable;
	private Map<String, String> fromProducts;
	
	@PostConstruct
    public void init() {
		payment = new Payment();
		// TODO - Load providers
		constructBillsList();
		constructProductsList();
    }
	
	public void constructBillsList() {
		
		billsAvailable = new LinkedHashMap<String, String>();
		List<Bill> bills = clientBean.getBills(sessionData.getClient());

		if(bills != null ) {
			for(Bill bill : bills) {
				billsAvailable.put(bill.getReference(), bill.getName());
			}
		}
	}
	
	private void constructProductsList() {
		
		fromProducts = new LinkedHashMap<String, String>();
		List<BankAccount> products = clientBean.getClientProducts(sessionData.getClient());
		
		if(products != null) {
			for(BankAccount account : products) {
				fromProducts.put(account.getAccountNumber(), (account.getType().toString() + formatAccountNumber(account.getAccountNumber())));
			}
		}
	}
	
	public String makePayment() {
		Transaction paymentTrx = paymentBean.makePayment(payment, accountId);
		if (!paymentTrx.isApproved()){
			FacesContext facesContext = FacesContext.getCurrentInstance();
			FacesMessage facesMessage = new FacesMessage(paymentTrx.getMessage());
			facesContext.addMessage(null, facesMessage);
			return "";
		}
		return "products";
	}
	
	public String formatAccountNumber(String accountNumber) {
		String protectedNumber = accountNumber.substring(0, accountNumber.length() - 4).replaceAll("[0-9]*", "*");
		return protectedNumber + accountNumber.substring(accountNumber.length() - 4);
	}

	public Map<String, String> getBillsAvailable() {
		return billsAvailable;
	}

	public void setBillsAvailable(Map<String, String> billsAvailable) {
		this.billsAvailable = billsAvailable;
	}

	public Payment getPayment() {
		return payment;
	}

	public void setPayment(Payment payment) {
		this.payment = payment;
	}

	public Map<String, String> getFromProducts() {
		return fromProducts;
	}

	public void setFromProducts(Map<String, String> fromProducts) {
		this.fromProducts = fromProducts;
	}

	public SessionData getSessionData() {
		return sessionData;
	}

	public void setSessionData(SessionData sessionData) {
		this.sessionData = sessionData;
	}

	public IClientBean getClientBean() {
		return clientBean;
	}

	public void setClientBean(IClientBean clientBean) {
		this.clientBean = clientBean;
	}

	public IPaymentBean getPaymentBean() {
		return paymentBean;
	}

	public void setPaymentBean(IPaymentBean paymentBean) {
		this.paymentBean = paymentBean;
	}

	public String getAccountId() {
		return accountId;
	}

	public void setAccountId(String accountId) {
		this.accountId = accountId;
	}
}
